//
//  ErrorHandling.swift
//  BJ12366Swift
//
//  Created by ZRAR on 16/2/29.
//  Copyright © 2016年 ZRAR. All rights reserved.
//

import UIKit

class ErrorHandling: NSObject {
    //表示并抛出错误
    enum VendingMachineError:ErrorType{
        case InvalidSelection //选择无效
        case InsufficientFunds(coninsNeeded:Int)//金额不足
        case OutOfStock
    }
    override init() {
        super.init()
        var vendingMach = VendingMachine()
        vendingMach.coinsDeposited = 8
        do{
            //try buyFavoriteSnack("Alice", vendingmachine: vendingMach)
        }catch VendingMachineError.InvalidSelection{
            
        }
       // throw VendingMachineError.InsufficientFunds(coninsNeeded: 5)
    }
    //处理错误，用throwing函数传递错误
    struct Item {
        
        var price:Int
        var count:Int
    }
    class VendingMachine {
        
        var inventory = ["Candy Bar":Item(price: 12, count: 7),"Chips":Item(price: 10, count: 4),"Pretzels":Item(price: 7, count: 11)]
        var coinsDeposited = 0
        func dispenseSnack(snack:String){
            print("Dispensing\(snack)")
        }
        func vend(itemNamed name:String) throws{
            guard var item = inventory[name] else{
                throw VendingMachineError.InvalidSelection
            }
            guard item.count>0 else{
                throw VendingMachineError.OutOfStock
            }
            guard item.price <= coinsDeposited else{
                throw VendingMachineError.InsufficientFunds(coninsNeeded: item.price - coinsDeposited)
            }
            coinsDeposited -= item.price
            --item.count
            inventory[name] = item
            dispenseSnack(name)
        }
    }
    let favoriteSnacks = [
        "Alice":"Chips",
        "Bob":"Licorice",
        "Eve":"Pretzels",
    ]
    func buyFavoriteSnack(person:String,vendingmachine:VendingMachine)throws{
        
        let snackName = favoriteSnacks[person] ?? "Candy Bar"
        try vendingmachine.vend(itemNamed: snackName)
        
    }
    //Do- Catch处理错误
     var y:Int = 0
    func dealWithError(){
       // do
        //buyFavoriteSnack("name", vendingmachine:VendingMachine
        do{
            y = try someThrowingFunction()
        }catch{
            
            y = 0
        }
        
    }
    //将错误转换成可选值
    func someThrowingFunction()throws ->Int{
        
        return 2
    }
    
    
    //Guard语句
    //与if语句相同的是，guard也是基于一个表达式的bool值去判断一段代码是否该被执行。
    //与if语句不同的是，guard只有在条件不满足的时候才会执行这段代码。你可以把guard近似的看做是Assert，但是你可以优雅的退出而非崩溃
    /**
        OC方法来保证一个变量真的存在并符合一个条件
        缺点：代码变得不好理解，如果
    */
    func fooManualCheck(x:Int?){
        if x == nil || x <= 0{
          print("不符合要求")
            return
        }
        //使用x
        x?.description
    }
    //Swift通过可选绑定让问题变得简单
    func fooBinding(x:Int?){
        if let x = x where x > 0{
            //使用
            x.description
        }
        //不符合条件
    }
    //guard语句
    func fooGuard(x:Int?){
        
        guard let x = x where x > 0 else{
            return
        }
        x.description
    }
    //对非可选类型的变量这种用法也是奏效的
    func fooNonOPtionalGood(x:Int){
        
        guard x > 0 else{
            return
        }
        
    }
}
